from datetime import datetime

from flask import request
from flask_restx import Namespace, Resource, fields
from flask_jwt_extended import jwt_required
from sqlalchemy import and_

# 导入 tb_alarm 模型
from app1.models import Zbfwb_tb_alarm
from app1 import db
from app1 import api

from app1.customdate import CustomDate

# 创建 Flask-RESTx 命名空间
ns_alarm = Namespace('nsalarm', description='Alarm operations')

# 使用 Flask-RESTx

alarm_model = ns_alarm.model('alarm', {
    "seq_num": fields.String(description='Seq num'),
    "occurrence_time": CustomDate(dt_format='str_time', description='Occurrence time'),
    "sys_name": fields.String(description='Sys name'),
    "dev_addr": fields.String(description='Dev addr'),
    "info": fields.String(description='Info'),
    "keyword": fields.String(description='Keyword'),
    "repeat_times": fields.Integer(description='Repeat times'),
    "last_update_time": CustomDate(dt_format='str_time', description='Last update time'),
    "level": fields.String(description='Level'),
    "kms_count": fields.Integer(description='Kms count'),
    "kms_id": fields.Integer(description='kms id')
})

alarm_seq_model = ns_alarm.model('alarm_seq_num', {
    "seq_num": fields.String(description='Seq num'),
})

alarm_sys_model = ns_alarm.model('alarm_sys', {
    "sys_name": fields.String(description='Sys name'),
})

alarm_devaddr_model = ns_alarm.model('alarm_devaddr', {
    "dev_addr": fields.String(description='Dev addr'),
})

alarm_level_model = ns_alarm.model('alarm_level', {
    "level": fields.String(description='Level'),
})

alarm_repeat_times_model = ns_alarm.model('alarm_repeat_times', {
    "repeat_times": fields.Integer(description='Repeat times'),
})

page_model = ns_alarm.model('page', {
    'page': fields.Integer(required=False, description='start page', default=1),
    'per_page': fields.Integer(required=False, description='per page', default=20),
    'max_page': fields.Integer(required=False, description='max page', default=50),
})

page_data_model = ns_alarm.model('pagedata', {
    'has_next': fields.Boolean(),  # has_next: 是否还有下一页
    'has_prev': fields.Boolean(),  # has_prev: 是否还有上一页
    'items': fields.List(fields.Nested(alarm_model)),  # items: 返回当前页的所有内容
    'next': fields.List(fields.Nested(alarm_model)),  # next(error_out=False): 返回下一页的Pagination对象
    'prev': fields.List(fields.Nested(alarm_model)),  # prev(error_out=False): 返回上一页的Pagination对象
    'page': fields.Integer(),  # page: 当前页的页码(从1开始)
    'pages': fields.Integer(),  # pages: 总页数
    'per_page': fields.Integer(),  # per_page: 每页显示的数量
    'prev_num': fields.Integer(),  # prev_num: 上一页页码数
    'next_num': fields.Integer(),  # next_num: 下一页页码数
    # query: 返回
    'total': fields.Integer()  # total: 查询返回的记录总数
})

pagedate_model = ns_alarm.model('pagedate', {
    # 'start_date': fields.DateTime(required=False, description='start date',dt_format='custom',
    #                               format='%Y-%m-%d %H:%M:%S.%f'),
    # 'end_date': fields.DateTime(required=False, description='end date'),

    'start_date': CustomDate(dt_format='str_time'),
    'end_date': CustomDate(dt_format='str_time'),
    'page': fields.Integer(required=False, description='start page', default=1),
    'per_page': fields.Integer(required=False, description='per page', default=20),
    'max_page': fields.Integer(required=False, description='max page', default=50),
})


@ns_alarm.route('/<string:seq_num>')
class AlarmSeqResource(Resource):
    @jwt_required()
    @ns_alarm.marshal_with(alarm_model)
    def get(self, seq_num):
        """Get user by user_id"""
        alarm = Zbfwb_tb_alarm.query.get(seq_num)
        if alarm:
            return alarm
        api.abort(404, f"alarm {seq_num} not found")


@ns_alarm.route('/alarmpage')
class AlarmPageResource(Resource):
    @jwt_required()
    @ns_alarm.marshal_with(page_data_model)
    @ns_alarm.expect(page_model)
    def post(self):
        """Get alarms by pages"""  # 接口说明紧跟在函数后面
        pagedata = api.payload

        # 获取分页请求信息
        page = pagedata['page']
        if page < 1:
            # default start page
            page = 1
        per_page = pagedata['per_page']
        if per_page < 1:
            # default per page
            per_page = 10

        error_out = False
        # 最大页数
        max_per_page = pagedata['max_page']

        # query
        pagealarms = Zbfwb_tb_alarm.query.paginate(page=page, per_page=per_page, error_out=error_out,
                                                   max_per_page=max_per_page)

        # has_next: 是否还有下一页
        # has_prev: 是否还有上一页
        # items: 返回当前页的所有内容
        # next(error_out=False): 返回下一页的Pagination对象
        # prev(error_out=False): 返回上一页的Pagination对象
        # page: 当前页的页码(从1开始)
        # pages: 总页数
        # per_page: 每页显示的数量
        # prev_num: 上一页页码数
        # next_num: 下一页页码数
        # query: 返回
        # total: 查询返回的记录总

        return pagealarms, 200


@ns_alarm.route('/alarmdatepage')
class AlarmBydateResource(Resource):

    # @jwt_required()
    @ns_alarm.marshal_with(page_data_model)
    @ns_alarm.expect(pagedate_model)
    def post(self):
        """Get alarms by date"""  # 接口说明紧跟在函数后面
        pagedatedata = api.payload

        # 获取分页请求信息
        start_date_str = pagedatedata['start_date']
        end_date_str = pagedatedata['end_date']

        # 将日期字符串转换为 datetime 对象
        start_date = datetime.strptime(start_date_str, '%Y-%m-%d %H:%M:%S.%f')
        end_date = datetime.strptime(end_date_str, '%Y-%m-%d %H:%M:%S.%f')

        print(start_date)
        print(end_date)

        # 查询并过滤数据
        # query = Zbfwb_tb_alarm.query.filter(and_(Zbfwb_tb_alarm.occurrence_time >= start_date,
        #                                          Zbfwb_tb_alarm.occurrence_time <= end_date))

        query = Zbfwb_tb_alarm.query.filter(
            Zbfwb_tb_alarm.occurrence_time.between(start_date, end_date)
        )
        # query = Zbfwb_tb_alarm.query.filter()

        # 计算总记录数
        total_records = query.count()

        print(total_records)

        # 获取分页请求信息
        page = pagedatedata['page']
        if page < 1:
            # default start page
            page = 1
        per_page = pagedatedata['per_page']
        if per_page < 1:
            # default per page
            per_page = 10

        error_out = False
        # 最大页数
        max_per_page = pagedatedata['max_page']

        # 计算每页显示的记录数
        per_page = max(1, total_records // max_per_page + (total_records % max_per_page > 0))

        # 分页查询
        alarms = query.paginate(page=page, per_page=per_page, error_out=False)

        return alarms, 200


@ns_alarm.route('/getbysysname')
class AlarmSysnameResource(Resource):

    @ns_alarm.expect(alarm_sys_model)
    # @jwt_required()
    @ns_alarm.marshal_with(alarm_model)
    def post(self):
        sysdata = api.payload

        sysname = sysdata['sys_name']

        alarm = Zbfwb_tb_alarm.query.filter_by(sys_name=sysname).all()

        # print(alarm)
        if alarm:
            return alarm
        api.abort(404, f"alarm {sysname} not found")


@ns_alarm.route('/getbydevaddr')
class AlarmDevResource(Resource):

    @ns_alarm.expect(alarm_devaddr_model)
    # @jwt_required()
    @ns_alarm.marshal_with(alarm_model)
    def post(self):
        devdata = api.payload

        devaddr = devdata['dev_addr']

        alarm = Zbfwb_tb_alarm.query.filter_by(dev_addr=devaddr).all()

        # print(alarm)
        if alarm:
            return alarm
        api.abort(404, f"alarm {devaddr} not found")


@ns_alarm.route('/getbylevel')
class AlarmLevelResource(Resource):

    @ns_alarm.expect(alarm_level_model)
    # @jwt_required()
    @ns_alarm.marshal_with(alarm_model)
    def post(self):
        leveldata = api.payload

        level = leveldata['level']

        alarm = Zbfwb_tb_alarm.query.filter_by(level=level).all()

        # print(alarm)
        if alarm:
            return alarm
        api.abort(404, f"alarm {level} not found")


@ns_alarm.route('/getbyrptimes')
class AlarmRptResource(Resource):

    @ns_alarm.expect(alarm_repeat_times_model)
    # @jwt_required()
    @ns_alarm.marshal_with(alarm_model)
    def post(self):
        rptdata = api.payload

        rptimes = rptdata['repeat_times']

        alarm = Zbfwb_tb_alarm.query.filter_by(repeat_times=rptimes).all()

        # print(alarm)
        if alarm:
            return alarm
        api.abort(404, f"alarm {rptimes} not found")


@ns_alarm.route('/getbyseqnum')
class AlarmSeqnumResource(Resource):

    @ns_alarm.expect(alarm_seq_model)
    # @jwt_required()
    @ns_alarm.marshal_with(alarm_model)
    def post(self):
        seqdata = api.payload

        seqnum = seqdata['seq_num']

        alarm = Zbfwb_tb_alarm.query.filter_by(seq_num=seqnum).all()

        # print(alarm)
        if alarm:
            return alarm
        api.abort(404, f"alarm {seqnum} not found")
